package com.ytb.service.Impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ytb.mapper.userMapper;
import com.ytb.pojo.login;
import com.ytb.pojo.user;
import com.ytb.service.IUserService;
import com.ytb.utils.JWTUtils;
import com.ytb.utils.Result;
import com.ytb.utils.ResultCode;
import com.ytb.utils.loginUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class userServiceImpl implements IUserService {

    @Autowired
    private userMapper uMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    public Result doWxLogin(login l){
        /*接收小程序发送的code
        开发者服务器 登录凭证校验接口 appi + appsecret + code
        接收微信接口服务 获取返回的参数
        校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        根据返回的User实体类，判断用户是否是新用户，是的话，将用户信息存到数据库；*/

        // 用户非敏感信息：rawData
        com.alibaba.fastjson.JSONObject rawDataJson = JSON.parseObject(l.getRawData());

        // 1.接收小程序发送的code
        // 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
        JSONObject json = JSONUtil.parseObj(loginUtils.getSessionKeyByWX(l.getCode()));
        String sessionKey = json.getStr("session_key");
        String signature2 = DigestUtils.sha1Hex(l.getRawData() + sessionKey);
        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        if (!(l.getSignature()).equals(signature2)) {
            return new Result(ResultCode.FAIL);
        }
        //判断是否是新用户
        if(json.getBool("isSuccess")) {
            // 通过 json.getStr("openid") 获取openid
            String openid = json.getStr("openid");
            // 根据openid判断新用户还是老用户
            LambdaQueryWrapper<user> lqw = Wrappers.lambdaQuery();
            lqw.eq(user::getOpenid,openid);
            user u = uMapper.selectOne(lqw);
            if (u == null){
                //   新用户，则随机注册一个账号（用户名、账号、用户ID），登录操作，返回token
                String userId = UUID.randomUUID().toString().toUpperCase();
                u = new user();
                // 用户信息入库
                String nickName = rawDataJson.getString("nickName");
                String avatarUrl = rawDataJson.getString("avatarUrl");
                u = new user();
                u.setOpenid(openid);
                u.setAvatarurl(avatarUrl);
                u.setNickname(nickName);
                u.setUtime(new Date());
                u.setCtime(new Date());
                u.setUserId(userId);
                uMapper.insert(u);
                return this.login(u);

            }else {
                //   老用户，登录操作，返回token
                return this.login(u);
            }
        }else {
            // 记录日志
            log.error("获取sessionkey失败! code = "+l.getCode());
            return Result.FAIL("登录失败! 无法获取openid！");
        }
    }

    //登录方法
    private Result login(user u) {
        System.out.println(u.getId());
        String token = JWTUtils.sign(u.getId());
        u.setToken(token);
        u.setOpenid(null);
        u.setUserId(null);
        u.setUtime(null);
        u.setCtime(null);
        //需要把token存入redis,下次访问需要登录资源的时候,可以根据token拿到详细信息
        //缓存
        String o = (String) redisTemplate.opsForValue().get("token_" + token);
        if (o != null){
            return Result.SUCCESS(u);
        }else {
            redisTemplate.opsForValue().set("token_"+token, JSON.toJSONString(u),7, TimeUnit.DAYS);
            return Result.SUCCESS(u);
        }
    }

}
